package cn.org.atool.generator.util;

import cn.org.atool.fluent.mybatis.base.BaseEntity;
import cn.org.atool.fluent.mybatis.base.IEntity;

import java.io.Serializable;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.HashSet;
import java.util.Set;

public interface FluentMybatisKit {
    static boolean isIEntity(Class klass) {
        return IEntity.class.isAssignableFrom(klass);
    }

    static boolean isBaseEntity(Class klass) {
        return BaseEntity.class.isAssignableFrom(klass);
    }

    /**
     * 有泛型定义
     *
     * @param klass entity class
     * @return true: 有泛型定义
     */
    static boolean hasEntityType(Class klass) {
        return hasEntityType(klass.getSimpleName(), klass.getTypeParameters());
    }

    /**
     * 泛型参数只有一个，且可以设置为Entity对象
     *
     * @param interfaceName 接口名称
     * @param typeVariables 接口泛型参数列表
     * @return ignore
     */
    static boolean hasEntityType(String interfaceName, TypeVariable[] typeVariables) {
        if (typeVariables.length != 1) {
            return false;
        }
        for (Type bound : typeVariables[0].getBounds()) {
            String tn = bound.getTypeName();
            // A<E extends A<E>> 形式判断
            if (tn.contains(interfaceName) || Allow_Entity_Bounds.contains(tn)) {
                return true;
            }
        }
        return false;
    }

    static boolean notBaseEntityClass(Class klass) {
        return !Allow_Entity_Bounds.contains(klass.getName());
    }

    /**
     * Entity自定义接口的泛型如果是下列类型子类型，可以使用Entity作为泛型参数
     */
    Set<String> Allow_Entity_Bounds = new HashSet<String>() {
        {
            this.add(Object.class.getName());
            this.add(Serializable.class.getName());
            this.add("cn.org.atool.fluent.mybatis.base.IEntity");
            this.add("cn.org.atool.fluent.mybatis.base.BaseEntity");
            this.add("cn.org.atool.fluent.mybatis.base.RichEntity");
        }
    };
}